<?php

namespace app\controller;

use app\BaseController;
use app\common\Amap;
use app\common\UsersService;
use app\model\Config;
use app\model\HkArea;
use app\model\Room;
use app\model\RoomComment;
use app\model\RoomRent;
use app\model\RoomTags;
use app\model\RoomType;
use app\model\Subway;
use app\model\UsersRelated;
use app\model\UsersShield;
use app\Request;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\db\Query;
use think\response\Json;

class RoomController extends BaseController
{

    protected array $middleware = [
        'Login' => ['except' => ['index', 'tags', 'test', 'area','read','comment_list','map','addRoom','map_detail','rent','room_type']],
        'Location' => ['only' => ['index','read']],
    ];
	
	/**
	 * 屏蔽
	 * @param Request $request
	 * @return void
	 */
	function shield(Request $request)
	{
		$id = $request->post('id/d');
		UsersShield::create([
			'users_id'=>$request->users_id,
			'pro_id'=>$id,
			'type'=>'room'
		]);
		writeJson();
	}
	
	
	/**
	 *房屋租赁-列表
	 * @param Request $request
	 * @param int $type
	 * @param string $keyword
	 * @param mixed $hk_area_id
	 * @param mixed $subway_id
	 * @param mixed $price_min
	 * @param mixed $price_max
	 * @param mixed $shi
	 * @param mixed $area_min
	 * @param mixed $area_max
	 * @param int $default
	 * @param int $rent_id
	 * @return Json
	 */
    function index(Request $request, int $type, string $keyword, mixed $hk_area_id, mixed $subway_id, mixed $price_min, mixed $price_max, mixed $shi, mixed $area_min, mixed $area_max, int $default, int $rent_id): Json
    {
	    $shield = UsersShield::where(['users_id'=>$request->users_id,'type'=>'room'])->column('pro_id');
	    
	    $lat = self::$latitude;
        $lng = self::$longitude;
	    $rent=null;
		if (!empty($rent_id)){
			$rent = RoomRent::find($rent_id);
		}
        $rows = Room::field("*,(6371 * acos (cos ( radians($lat) ) * cos( radians( latitude ) ) * cos( radians(longitude) - radians( $lng ) ) + sin ( radians( $lat ) ) * sin( radians( latitude ) ))) AS distance")
            ->where(['type' => $type])
            ->with([
                'users',
                'users_collect' => function (Query $query) use ($request) {
                    $query->where(['users_id' => $request->users_id, 'type' => 'room']);
                },
                'users_like' => function (Query $query) use ($request) {
                    $query->where(['users_id' => $request->users_id, 'type' => 'room']);
                }])
            ->filter(function ($data) use($lat,$lng) {
                if (empty($lat) || empty($lng)) {
                    $data->distance_text = '';
                } else {
                    if ($data->distance == 0) {
                        $data->distance_text = '0m';
                    } elseif (0 < $data->distance && $data->distance < 1) {
                        $data->distance_text = bcmul((string)$data->distance, '1000') . 'm';
                    } else {
                        $data->distance_text = bcmul((string)$data->distance, '1', 1) . 'km';
                    }
                }

            })
	        ->whereNotIn('id',$shield)
	        ->when(!empty($rent),function (Query $query)use($type,$rent_id,$rent){
		        if (in_array($type,[1,3])){
			        $query->whereBetween('room_price', [$rent->min_price, $rent->max_price]);
		        }else{
			        $query->where(['rent_id' => $rent_id]);
		        }
	        })
	        ->when(!empty($hk_area_id)&&$hk_area_id!=3, function (Query $query) use ($hk_area_id) {
		        $query->whereFindInSet('hk_area_ids',$hk_area_id);
	        })
            ->when(!empty($subway_id), function (Query $query) use ($subway_id) {
                $query->where(['subway_id' => $subway_id]);
            })
            ->when(!empty($price_min) && !empty($price_max), function (Query $query) use ($price_min,$type, $price_max) {
				if (in_array($type,[1,3])){
					$query->whereBetween('room_price', [$price_min, $price_max]);
				}
            })
	        ->when(!empty($rent_id),function (Query $query)use($rent_id,$type){
		        if ($type == 2){
			        $query->where(['rent_id' => $rent_id]);
				}
	        })
            ->when(!empty($shi), function (Query $query) use ($shi) {
                switch ($shi) {
                    case 5:
                        $query->where('shi', '>=', 5);
                        break;
                    default:
                        $query->where(['shi' => $shi]);
                }
            })
            ->when(!empty($area_min) && !empty($area_max), function (Query $query) use ($area_min, $area_max) {
                $query->whereBetween('room_area', [$area_min, $area_max]);
            })
            ->when(!empty($default), function (Query $query) use ($default,$lat,$lng) {
                switch ($default) {
                    case 1:
                        $query->order(['id' => 'desc']);
                        break;
                    case 2:
                        $query->order('browse', 'desc');
                        break;
                    case 3:
                        $query->order('createtime', 'desc');
                        break;
                    case 4:
                        $query->where('images', '<>', '');
                        break;
                    case 5:
                        if (empty($lat)||empty($lng)){
                            $query->order('createtime', 'desc');
                        }else{
                            $query->order('distance', 'asc');
                        }
                        break;
                }
            })
            ->when(!empty($keyword), function (Query $query) use ($keyword) {
                $query->whereLike('room_name', '%' . $keyword . '%');
            })
            ->paginate()
            ->items();

        writeJson($rows);
    }
	
	/**
	 * 房屋类型
	 * @return void
	 */
	function room_type()
	{
		$rows = RoomType::order(['weigh'=>'desc'])->select();
		writeJson($rows);
	}
	
	/**
	 * 地图找房
	 * @return Json
	 */
	function map(float $latitude,float $longitude,int $distance,int $type, string $keyword, mixed $hk_area_id, mixed $subway_id, mixed $price_min, mixed $price_max, mixed $shi, mixed $area_min, mixed $area_max, int $default, int $rent_id)
	{

		$lat = $latitude;
		$lng = $longitude;
		$rent=null;
		if (!empty($rent_id)){
			$rent = RoomRent::find($rent_id);
		}
		$res = Room::field("*,(6371 * acos (cos ( radians($lat) ) * cos( radians( latitude ) ) * cos( radians(longitude) - radians( $lng ) ) + sin ( radians( $lat ) ) * sin( radians( latitude ) ))) AS distance")
			->where(['type' =>$type])
			->filter(function ($data) use($lat,$lng) {
				if (empty($lat) || empty($lng)) {
					$data->distance_text = '';
				} else {
					if ($data->distance == 0) {
						$data->distance_text = '0m';
					} elseif (0 < $data->distance && $data->distance < 1) {
						$data->distance_text = bcmul((string)$data->distance, '1000') . 'm';
					} else {
						$data->distance_text = bcmul((string)$data->distance, '1', 1) . 'km';
					}
				}
			})
			->when(!empty($rent),function (Query $query)use($type,$rent_id,$rent){
				if (in_array($type,[1,3])){
					$query->whereBetween('room_price', [$rent->min_price, $rent->max_price]);
				}else{
					$query->where(['rent_id' => $rent_id]);
				}
			})
			->when(!empty($hk_area_id)&&$hk_area_id!=3, function (Query $query) use ($hk_area_id) {
				$query->where(['hk_area_ids' => $hk_area_id]);
			})
			->when(!empty($subway_id), function (Query $query) use ($subway_id) {
				$query->where(['subway_id' => $subway_id]);
			})
			->when(!empty($price_min) && !empty($price_max), function (Query $query) use ($price_min, $price_max) {
				$query->whereBetween('room_price', [$price_min, $price_max]);
			})
			->when(!empty($shi), function (Query $query) use ($shi) {
				switch ($shi) {
					case 5:
						$query->where('shi', '>=', 5);
						break;
					default:
						$query->where(['shi' => $shi]);
				}
			})
			->when(!empty($area_min) && !empty($area_max), function (Query $query) use ($area_min, $area_max) {
				$query->whereBetween('room_area', [$area_min, $area_max]);
			})
			->when(!empty($default), function (Query $query) use ($default) {
				switch ($default) {
					case 1:
						$query->order(['id' => 'desc']);
						break;
					case 2:
						$query->order('browse', 'desc');
						break;
					case 3:
						$query->order('createtime', 'desc');
						break;
					case 4:
						$query->where('images', '<>', '');
						break;
					case 5:
						if (empty($lat)||empty($lng)){
							$query->order('createtime', 'desc');
						}else{
							$query->order('distance', 'asc');
						}
						break;
				}
			})
			->when(!empty($keyword), function (Query $query) use ($keyword) {
				$query->whereLike('room_name', '%' . $keyword . '%');
			})
			->having("distance<=$distance")
			->select();
		writeJson($res);
	}
	
	function map_detail(Request $request)
	{
		$params = $this->request->param();//type 类型:1=出租 , 3=出售 经度lng  纬度lat  当前distance
		$lat = $params['latitude'];
		$lng = $params['longitude'];
		$res = Room::field("*,(6371 * acos (cos ( radians($lat) ) * cos( radians( latitude ) ) * cos( radians(longitude) - radians( $lng ) ) + sin ( radians( $lat ) ) * sin( radians( latitude ) ))) AS distance")
			->where(['type' => $params['type'],'longitude'=>$lng,'latitude'=>$lat])
			->with([
				'users',
				'users_collect' => function (Query $query) use ($request) {
					$query->where(['users_id' => $request->users_id, 'type' => 'room']);
				},
				'users_like' => function (Query $query) use ($request) {
					$query->where(['users_id' => $request->users_id, 'type' => 'room']);
				}])
			->filter(function ($data) use($lat,$lng) {
				if (empty($lat) || empty($lng)) {
					$data->distance_text = '';
				} else {
					if ($data->distance == 0) {
						$data->distance_text = '0m';
					} elseif (0 < $data->distance && $data->distance < 1) {
						$data->distance_text = bcmul((string)$data->distance, '1000') . 'm';
					} else {
						$data->distance_text = bcmul((string)$data->distance, '1', 1) . 'km';
					}
				}
			})
			->select();
		writeJson($res);
	}

    /**
     *
     * 房屋详情
     * @param int $id
     * @param Request $request
     * @return Json
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function read(int $id, Request $request): Json
    {
        $lat = self::$latitude;
        $lng = self::$longitude;
        $res = Room::field("*,(6371 * acos (cos ( radians($lat) ) * cos( radians( latitude ) ) * cos( radians(longitude) - radians( $lng ) ) + sin ( radians( $lat ) ) * sin( radians( latitude ) ))) AS distance")
            ->with([
                'users',
                'users_collect' => function (Query $query) use ($request) {
                    $query->where(['users_id' => $request->users_id, 'type' => 'room']);
                },
                'users_like' => function (Query $query) use ($request) {
                    $query->where(['users_id' => $request->users_id, 'type' => 'room']);
                }])
            ->filter(function ($data) use($lat,$lng) {

                if (empty($lat) || empty($lng)) {
                    $data->distance_text = '';
                } else {
	                if (empty($data->latitude)||empty($data->longitude)){
		                $data->distance_text = '';
	                }else{
		                if ($data->distance == 0) {
			                $data->distance_text = '0m';
		                } elseif (0 < $data->distance && $data->distance < 1) {
			                $data->distance_text = bcmul((string)$data->distance, '1000') . 'm';
		                } else {
			                $data->distance_text = bcmul((string)$data->distance, '1', 1) . 'km';
		                }
	                }
                }
                if (in_array($data->type, [1, 3])) {
                    $data->staticmap = 'https://restapi.amap.com/v3/staticmap?location=' . $data->longitude . ',' .
                        $data->latitude . '&zoom=15&size=1080*720&labels=' . $data->room_name . ',2,0,16,0xFFFFFF,0x008000:' .
                        $data->longitude . ',' . $data->latitude . '&key=' . Config::getFieldByName('gaode_ak', 'value');
                }})
            ->find($id);
        
        UsersService::footmark($id, $request->users_id, 'room');
	    event('RoomIncBrowse', $id); //增加浏览数量
        writeJson($res);
    }


    /**
     * 评论
     * @param Request $request
     * @return Json
     */
    function comment(Request $request): Json
    {
        $params = $request->param();
        $ip = $request->ip();
        $params['ip'] = $ip;
        $ip = Amap::ip($ip);
        $ip = json_decode($ip);
        if ($ip->status == 1) {
            $params['city'] = $ip->province;
        } else {
            $params['city'] = '未知';
        }
        $res = RoomComment::create($params);
        foreach ($params['content'] as $v) {
            if ($v['type'] == 'at') {
                //@提醒  提醒接收人
                UsersRelated::create(['users_id' => $v['userId'], 'type' => 8, 'from_users_id' => $request->users_id, 'scene' => 'Room', 'pro_id' => $res->id]);
            }
        }
        if (!empty($params['to_users_id'])) {
            //回复提醒  提醒接收人
            UsersRelated::create(['users_id' => $params['to_users_id'], 'type' => 1, 'from_users_id' => $request->users_id, 'scene' => 'Room', 'pro_id' => $res->id]);
        } else {
            //评论提醒  提醒发布人
            $pro = Room::find($params['room_id']);
            UsersRelated::create(['users_id' => $pro->users_id, 'type' => 2, 'from_users_id' => $request->users_id, 'scene' => 'Room', 'pro_id' => $res->id]);
        }
        event('RoomIncComment', $params['room_id']); //增加评论数量
        $row = RoomComment::with(['users', 'to_users', 'users_like' => function (Query $query) use ($request) {
            $query->where(['users_id' => $request->users_id, 'type' => 'room_comment']);
        }])->find($res->id);
        writeJson($row);
    }

    /**
     * 评论列表
     * @param int $room_id
     * @param mixed $comment_id
     * @param Request $request
     * @return Json
     */
    function comment_list(int $room_id, mixed $comment_id, Request $request)
    {

        $top_id = 0;
        if (!empty($comment_id)) {
            $row = RoomComment::find($comment_id);
            if ($row->pid == 0) {
                //顶级评论 放在第一条
                $top_id = $row->id;
            } else {
                //子评论 找出顶级评论
                $row = RoomComment::find($row->pid);
                $top_id = $row->id;
            }
        }
        $rows = RoomComment::where(['pid' => 0, 'room_id' => $room_id])
            ->withCount('comment')
            ->with([
                'users',
                'comment' => function (Query $query) use ($request, $comment_id) {
                    $query
                        ->with(['users', 'to_users', 'users_like' => function (Query $query) use ($request) {
                            $query->where(['users_id' => $request->users_id, 'type' => 'room_comment']);
                        }])
                        ->when(!empty($comment_id), function (Query $query) use ($comment_id) {
                            $query->field("*,IF(id = $comment_id,1,0) AS top")->order(['top' => 'desc', 'id' => 'desc']);
                        }, function (Query $query) {
                            $query->order(['id' => 'desc']);
                        })
                        ->limit($this->comment_list_rows);
                },
                'users_like' => function (Query $query) use ($request) {
                    $query->where(['users_id' => $request->users_id, 'type' => 'room_comment']);
                }])
            ->when(!empty($comment_id), function (Query $query) use ($top_id) {
                $query->field("IF(id = $top_id,1,0) AS top")->order(['top' => 'desc', 'id' => 'desc']);
            }, function (Query $query) {
                $query->order(['id' => 'desc']);
            })
            ->paginate()
            ->items();
        writeJson($rows);
    }

    /**
     * 评论详情
     * @param int $id
     * @param mixed $comment_id
     * @param Request $request
     * @return Json
     */
    function comment_detail(int $id, mixed $comment_id, Request $request): Json
    {
        $child = false;
        if (!empty($comment_id)) {
            $row = RoomComment::find($comment_id);
            if ($row->pid != 0) {
                //二级评论
                $child = true;
            }
        }
        $rows = RoomComment::where(['pid' => $id])
            ->with(['users', 'to_users', 'users_like' => function (Query $query) use ($request) {
                $query->where(['users_id' => $request->users_id, 'type' => 'room_comment']);
            }])
            ->when($child, function (Query $query) use ($comment_id) {
                $query->where('id', '<>', $comment_id);
            })
            ->order(['id' => 'desc'])
            ->paginate($this->comment_detail_rows)
            ->items();
        writeJson($rows);
    }

    /**
     * 地区
     * @return Json
     */
    function area()
    {
        $HkArea = HkArea::with(['class' => function (Query $query) {
            $query->with(['class']);
        }])->where(['pid' => 0])->select();
        $Subway = Subway::with(['class' => function (Query $query) {
            $query->with(['class']);
        }])->where(['pid' => 0])->select();
        writeJson(['area' => $HkArea, 'subway' => $Subway]);
    }

    /**
     * 评论点赞
     * @param Request $request
     * @return Json
     */
    function comment_like(Request $request)
    {
        $id = $request->param('id');
        $res = UsersService::like($id, $request->users_id, 'room_comment');
        $res ? event('RoomCommentIncLike', $id) : event('RoomCommentDecLike', $id); //增加/减少  点赞数量
        if ($res) {
            $pro = RoomComment::find($id);
            UsersRelated::create(['users_id' => $pro->users_id, 'type' => 4, 'from_users_id' => $request->users_id, 'scene' => 'Room', 'pro_id' => $id]);
        }
        writeJson($res);
    }


    /**
     * 房屋租赁-发布
     * @return Json
     */
    function save(Request $request)
    {
        $params = $request->param();
	    if (!empty($params['longitude'])&&!empty($params['latitude'])){
		    $ids = HkArea::where([['top','>=',$params['latitude']],['bottom','<=',$params['latitude']],['left','<=',$params['longitude']],['right','>=',$params['longitude']]])->column('id');
			$ids = implode(',',$ids);
		    $params['hk_area_ids'] = $ids;
	    }
		if (!empty($params['rent_id'])){
			$row = RoomRent::find($params['rent_id']);
			$params['start_price'] = $row->min_price;
			$params['end_price'] = $row->max_price;
		}
	    $res = Room::create($params);
        writeJson($res->append(['users']));
    }


    /**
     * 房屋租赁-标签
     * @return Json
     */
    function tags()
    {
        $res = RoomTags::with(['tags'])->where(['pid' => 0])->select();
        writeJson($res);
    }

    /**
     * 点赞
     * @param Request $request
     * @return Json
     */
    function like(Request $request)
    {
        $id = $request->post('id');
        $res = UsersService::like($id, $request->users_id, 'room');
        $res ? event('RoomIncLike', $id) : event('RoomDecLike', $id); //增加/减少  点赞数量
        if ($res) {
            $pro = Room::find($id);
            UsersRelated::create(['users_id' => $pro->users_id, 'type' => 3, 'from_users_id' => $request->users_id, 'scene' => 'Room', 'pro_id' => $id]);
        }
        writeJson($res);
    }

    /**
     * 收藏
     * @param Request $request
     * @return Json
     */
    function collect(Request $request)
    {
        $id = $request->post('id');
        $res = UsersService::collect($id, $request->users_id, 'room');
        $res ? event('RoomIncCollect', $id) : event('RoomDecCollect', $id); //增加/减少  收藏数量
        if ($res) {
            $pro = Room::find($id);
            UsersRelated::create(['users_id' => $pro->users_id, 'type' => 7, 'from_users_id' => $request->users_id, 'scene' => 'Room', 'pro_id' => $id]);
        }
        writeJson($res);
    }
	
	
	function addRoom()
	
	{
//		$list=Room::where('id','>=',1644)->select();
//		foreach ($list as $key=>$item) {
//			$item->save(['room_name'=>'出售房屋'.$key+1]);
//		}
//
//		dd(111);
	
		for ($i=201;$i<=300;$i++){
			$a='114.16'.rand(1000,9999);
			$b='22.29'.rand(1000,9999);
			$longitude = $a;
			$latitude = $b;

			$data=[
				'users_id'=>6,
				'type'=>3,
				'longitude'=>$longitude,
				'latitude'=>$latitude,
				'room_name'=>'出售房屋'.$i
			];
			Room::create($data);
		}
	}
	
	/**
	 * 删除
	 * @param Request $request
	 * @return Json
	 */
    function delete(Request $request)
    {
        $id = $request->post('id/d');
        $row = Room::where(['users_id' => $request->users_id, 'id' => $id])->findOrFail();
        $row->delete();
        writeJson();
    }
	
	/**
	 * 上架/下架
	 * @param Request $request
	 * @return Json
	 */
    function up_down(Request $request)
    {
        $id = $request->post('id/d');
        $status = $request->post('status/d');
        $row = Room::where(['users_id' => $request->users_id, 'id' => $id])->findOrFail();
        $row->save(['status' => $status]);
        writeJson();
    }
	
	/**
	 * 编辑
	 * @param Request $request
	 * @return Json
	 */
    function edit(Request $request)
    {
        $params = $request->param();
        $row = Room::findOrFail($params['id']);
        if ($request->isGet()) {
            writeJson($row);
        }
        $row->save($params);
        writeJson();
    }
	
	/**
	 * 房屋金额
	 * @param int $type
	 * @return void
	 */
	function rent(int $type)
	{
		$rows = RoomRent::where(['type'=>$type])->order(['weigh'=>'desc'])->select();
		writeJson($rows);
	}


}